#if UNITY_EDITOR
using GameDesigner;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

public class ScriptTools : MonoBehaviour
{
    /// <summary>
    /// path = Application.dataPath + @"GameDesigner\Skill\StateAction"
    /// </summary>
    public static void CreateScript(string path, string scriptName, string textContents)
    {
        if (Directory.Exists(path) == false)
            Directory.CreateDirectory(path);
        File.AppendAllText(path + "/" + scriptName + ".cs", textContents);
        AssetDatabase.Refresh();
    }

    /// <summary>
    /// path = Application.dataPath + @"GameDesigner\Skill\StateAction"
    /// </summary>
    public static void CreateScript(string path, string scriptName, string[] scriptText)
    {
        if (Directory.Exists(path) == false)
            Directory.CreateDirectory(path);
        foreach (var str in scriptText)
        {
            File.AppendAllText(path + "/" + scriptName + ".cs", str + "\n");
        }
        AssetDatabase.Refresh();
    }

    [MenuItem("CONTEXT/StateManager/生成代码")]
    private static void StateManagerGenerateCode(MenuCommand menuCommand)
    {
        var target = menuCommand.context as StateManager;
        if (target == null)
            return;
        if (target.support == null)
            return;
        GenerateCode(target.support);
    }

    [MenuItem("CONTEXT/StateMachineView/生成代码")]
    private static void StateMachineViewGenerateCode(MenuCommand menuCommand)
    {
        var support = menuCommand.context as StateMachineView;
        if (support == null)
            return;
        GenerateCode(support);
    }

    private static void GenerateCode(StateMachineView support)
    {
        var codeBuilder = new StringBuilder();
        codeBuilder.AppendLine("public static StateController CreateStateController(object self)");
        codeBuilder.AppendLine("{");
        codeBuilder.AppendLine("\tvar controller = new StateController() { Self = self };");
        var controller = support.controller;
        var layers = controller.layers;
        for (int i = 0; i < layers.Length; i++)
        {
            var layer = layers[i];
            codeBuilder.AppendLine($"\tvar layer{i} = controller.AddNewLayer(\"{layer.name}\");");
            var states = layer.stateMachine.States;
            for (int y = 0; y < states.Length; y++)
            {
                var state = states[y];
                var actionSystem = state.actionSystem ? "true" : "false";
                var animLoop = state.animLoop ? "true" : "false";
                var isCrossFade = state.isCrossFade ? "true" : "false";
                var isExitState = state.isExitState ? "true" : "false";
                var dstStateID = state.dstStateID;
                var codeBehaviours = string.Empty;
                var behaviours = state.behaviours;
                for (int b = 0; b < behaviours.Length; b++)
                {
                    if (b == behaviours.Length - 1)
                        codeBehaviours += $"new {behaviours[b].name}()";
                    else
                        codeBehaviours += $"new {behaviours[b].name}(),";
                }
                if (string.IsNullOrEmpty(codeBehaviours))
                    codeBehaviours = "null";
                codeBuilder.AppendLine($"\tvar {state.name}State = layer{i}.stateMachine.AddState(\"{state.name}\", {actionSystem}, {animLoop}, {isCrossFade}, {isExitState}, {dstStateID}, {codeBehaviours});");
                for (int z = 0; z < state.actions.Length; z++)
                {
                    var action = state.actions[z];
                    behaviours = action.behaviours;
                    codeBehaviours = string.Empty;
                    for (int b = 0; b < behaviours.Length; b++)
                    {
                        if (b == behaviours.Length - 1)
                            codeBehaviours += $"new {behaviours[b].name}()";
                        else
                            codeBehaviours += $"new {behaviours[b].name}(),";
                    }
                    if (string.IsNullOrEmpty(codeBehaviours))
                        codeBehaviours = "null";
                    codeBuilder.AppendLine($"\t{state.name}State.SetActionProperty({z}, \"{action.clipName}\", 0f, {action.length}f, {action.animTimeMax}f, {codeBehaviours});");
                }
                var transitions = state.transitions;
                for (int z = 0; z < transitions.Length; z++)
                {
                    var transition = transitions[z];
                    behaviours = transition.behaviours;
                    codeBehaviours = string.Empty;
                    for (int b = 0; b < behaviours.Length; b++)
                    {
                        if (b == behaviours.Length - 1)
                            codeBehaviours += $"new {behaviours[b].name}()";
                        else
                            codeBehaviours += $"new {behaviours[b].name}(),";
                    }
                    if (string.IsNullOrEmpty(codeBehaviours))
                        codeBehaviours = "null";
                    codeBuilder.AppendLine($"\t{state.name}State.AddTransition({transition.NextId}, TransitionMode.{transition.mode}, {transition.exitTime}f, {transition.actionId}, {codeBehaviours});");
                }
            }
        }
        codeBuilder.AppendLine("\tcontroller.Init((layer) => new TimeStateMachine());");
        codeBuilder.AppendLine("\treturn controller;");
        codeBuilder.AppendLine("}");
        StateMachineCodeWindow.ShowWindow(codeBuilder.ToString());
    }
}
#endif